﻿using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace WebApi.Infrastructure
{
    /// <summary>
    /// 2019-04-24 json序列化 
    /// </summary>
    public static class JsonOperator
    {
        /// <summary>
        /// Json 序列化
        /// </summary>
        /// <param name="value"></param>
        /// <param name="converters"></param>
        /// <returns></returns>
        public static string JsonSerialize(object value, string[] columnArr, params JsonConverter[] converters)
        {
            if (value != null)
            {
                if (converters != null && converters.Length > 0)
                {
                    return JsonConvert.SerializeObject(value, converters);
                }
                else
                {
                    return JsonConvert.SerializeObject(value);
                }
            }
            return string.Empty;
        }


        /// <summary>
        ///  2019-04-24 支持列筛选的序列化
        /// </summary>
        /// <param name="value"></param>
        /// <param name="columnArr"></param>
        /// <returns></returns>
        public static string JsonSerialize(object value, string[] columnArr)
        {
            return JsonConvert.SerializeObject(value, GetJsongSettings(columnArr));
        }


        /// <summary>
        /// 2019-04-24 有选择性的序列化[日志默认按标准格式处理]
        /// </summary>
        /// <param name="columnNameArray"></param>
        /// <returns></returns>
        private static JsonSerializerSettings GetJsongSettings(string[] columnNameArray)
        {

            IsoDateTimeConverter timeConverter = new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
            if (columnNameArray == null || columnNameArray.Length == 0)
            {
                JsonSerializerSettings jsetting = new JsonSerializerSettings()
                {
                    Converters = { timeConverter }
                };


                return jsetting;
            }
            else
            {
                JsonSerializerSettings jsetting = new JsonSerializerSettings()
                {
                    ContractResolver = new LimitPropsContractResolver(columnNameArray),
                    Converters = { timeConverter }
                };
                return jsetting;
            }
        }



        /// <summary>
                /// Json反序列化
                /// </summary>
                /// <typeparam name="T"></typeparam>
                /// <param name="value"></param>
                /// <param name="converters"></param>
                /// <returns></returns>
        public static T JsonDeserialize<T>(string value, params JsonConverter[] converters)
        {
            if (string.IsNullOrEmpty(value))
                return default(T);


            if (converters != null && converters.Length > 0)
            {
                return JsonConvert.DeserializeObject<T>(value, converters);
            }
            else
            {
                Type type = typeof(T);


                //if (type == typeof(DataSet))
                //{
                //    return JsonConvert.DeserializeObject<T>(value, new DataSetConverter());
                //}
                //else if (type == typeof(DataTable))
                //{
                //    return JsonConvert.DeserializeObject<T>(value, new DataTableConverter());
                //}
                return JsonConvert.DeserializeObject<T>(value);
            }
        }
    }

    /// <summary>
    /// 属性筛选器
    /// </summary>
    public class LimitPropsContractResolver : DefaultContractResolver
    {
        string[] props = null;

        bool retain;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="props">传入的属性数组</param>
        /// <param name="retain">true:表示props是需要保留的字段  false：表示props是要排除的字段</param>
        public LimitPropsContractResolver(string[] props, bool retain = true)
        {
            //指定要序列化属性的清单
            this.props = props;

            this.retain = retain;
        }

        protected override IList<JsonProperty> CreateProperties(Type type,

        MemberSerialization memberSerialization)
        {
            IList<JsonProperty> list =
            base.CreateProperties(type, memberSerialization);
            //只保留清单有列出的属性
            return list.Where(p =>
            {
                if (retain)
                {
                    return props.Contains(p.PropertyName);
                }
                else
                {
                    return !props.Contains(p.PropertyName);
                }
            }).ToList();
        }
    }

}
